/**
 * \file       xml.cpp
 * \brief      source codes for process xml data
 * \version    1.0
 * \author     dragon,chinagnu@gmail.com
 * \date       2008-05-02
 * \remarks    there is initial Version
 * \bug        unknown
 * \todo       process xml data
 *
 * <HR>
 * \version    1.1
 * \author     dragon,chinagnu@gmail.com
 * \date       2008-05-06
 * \remarks    add some function into this class
 *
 * <HR>
 * \version    1.2
 * \author     dragon,chinagnu@gmail.com
 * \date       2008-05-08
 * \remarks    remove create_config_file, modify add_dir_into_list
 *
 * <HR>
 * \version    1.3
 * \author     dragon,chinagnu@gmail.com
 * \date       2008-05-09
 * \remarks    create .dolphin directory to user's home directory 
 *             and save play list configure file into this resource 
 *             directory
 *
 * <HR>
 * \version    1.4
 * \author     dragon,chinagnu@gmail.com
 * \date       2008-05-09
 * \remarks    fixed a bug of clean all old records of configure 
 *             file when user add a file into play list on the first
 *             time 
 * <HR>
 * \version    1.5
 * \author     dragon,chinagnu@gmail.com
 * \date       2008-05-15
 * \remarks    update get_basename function
 *
 * <HR>
 * \version    1.6
 * \author     dragon,chinagnu@gmail.com
 * \date       2008-05-15
 * \remarks    add get_alisa
 * \bug        fixed a bug of search media files from a directory.
 *
 * <HR>
 * \version    1.7
 * \author     dragon,chinagnu@gmail.com
 * \date       2008-05-15
 * \remarks    add get_alisa
 * \bug        add method check_list_file into this class
 */

#include "xml.h"

/**  
  *  inital of class XMLProcess
  */ 
XMLProcess::XMLProcess(void)
{
	 first_load_flag=1;
	 string res_dir;
	 res_dir.append(getenv("HOME"));
	 res_dir.append("/");
	 res_dir.append(".dolphin");
	 d_res_dir = wxString(res_dir.c_str(),wxConvUTF8);

	 if(access(res_dir.c_str(),X_OK) != 0)
	 {
		  mkdir(res_dir.c_str(),S_IRWXU|S_IRWXG);
	 }

     init_media_type();
     init_write_handle();
}

XMLProcess::~XMLProcess(void)
{
     delete media_type;
}


void XMLProcess::init_media_type(void)
{
     media_type = new wxArrayString();
     media_type->Add(_T("ogg"));
     media_type->Add(_T("OGG"));
     media_type->Add(_T("mp3"));
     media_type->Add(_T("MP3"));
     media_type->Add(_T("asf"));
     media_type->Add(_T("ASF"));
     media_type->Add(_T("mpg"));
     media_type->Add(_T("MPG"));
     media_type->Add(_T("wma"));
     media_type->Add(_T("WMA"));
     media_type->Add(_T("avi"));
     media_type->Add(_T("AVI"));
     media_type->Add(_T("wmv"));
     media_type->Add(_T("WMV"));
     media_type->Add(_T("mp4"));
     media_type->Add(_T("MP4"));
}

bool XMLProcess::check_list_file(wxString filename)
{
	 wxString res_file=d_res_dir;
	 res_file.Append(_T("/"));
	 res_file.Append(filename);
	 
	 if(wxFile::Exists(res_file.c_str()))
		  return true;
	 else
		  return false;	 
}

wxString XMLProcess::get_basename(wxString name)
{
	 if (name == wxEmptyString)
	 {
		  return wxEmptyString;
	 }

	 wxFileName *fn = new wxFileName(name,wxPATH_NATIVE);
	 wxString shortname = fn->GetFullName();
	 
     return shortname;
}

wxString XMLProcess::get_alias(wxString name)
{
	 if (name == wxEmptyString)
	 {
		  return wxEmptyString;
	 }

	 wxString shortname = get_basename(name);
	 wxString target = shortname.BeforeLast('.');
	 
	 return target;
}

uint32_t XMLProcess::get_media_file(wxString filename)
{
     wxString name = filename.AfterLast('.');
     for (uint32_t i=0;i<media_type->GetCount();i++)
     {
		  if (name.Cmp(media_type->Item(i)) == 0)
		  {
			   return 1;
		  }
     }     
     return 0;
}

void XMLProcess::add_dir_to_list(wxString conf_file,wxArrayString *list,wxArrayString *files)
{
	 wxXmlNode* node;
	 wxString res_file=d_res_dir;
	 res_file.Append(_T("/"));
	 res_file.Append(conf_file);

	 if(first_load_flag == 1)
	 {
		  if (list != NULL && (!list->IsEmpty()))
		  {
			   for (uint32_t i=0;i<list->GetCount();i++)
			   {
					node = create_record(_T("record"),list->Item(i));
					root->AddChild(node);					
			   }			   
		  }
		  first_load_flag = 0;
	 }
	 
	 for (uint32_t i=0;i<files->GetCount();i++)
	 {
		  wxString alias = get_basename(files->Item(i));
		  if (get_media_file(alias) != 0)
		  {
			   node = create_record(_T("record"),files->Item(i));
			   root->AddChild(node);
		  }
	 }

	 w_doc.DetachRoot();
	 w_doc.SetRoot(root);
	 w_doc.Save(res_file);
}

void XMLProcess::add_file_to_list(wxString conf_file,wxArrayString *list,wxString filename)
{
	 wxString res_file=d_res_dir;
	 res_file.Append(_T("/"));
	 res_file.Append(conf_file);

	 wxString alias = get_basename(filename);
	 if (get_media_file(alias) != 0)
	 {
		  wxXmlNode* node;
		  if(first_load_flag == 1)
		  {
			   if (list != NULL && (!list->IsEmpty()))
			   {
					for (uint32_t i=0;i<list->GetCount();i++)
					{
						 node = create_record(_T("record"),list->Item(i));
						 root->AddChild(node);					
					}			   
			   }
			   first_load_flag = 0;
		  }
		  node = create_record(_T("record"),filename);
		  root->AddChild(node);		  		  

		  w_doc.DetachRoot();
		  w_doc.SetRoot(root);
		  w_doc.Save(res_file);
	 }
}


//  create xml configure file
void XMLProcess::init_write_handle(void)
{
     root = new wxXmlNode(NULL,wxXML_ELEMENT_NODE,_T("list"),wxEmptyString, NULL, NULL);	
}

wxXmlNode* XMLProcess::create_record(wxString tag,wxString path)
{
	 wxXmlNode* child = new wxXmlNode(wxXML_ELEMENT_NODE,tag,wxEmptyString);
	 wxXmlNode* info = new wxXmlNode(wxXML_TEXT_NODE,wxEmptyString,wxEmptyString);
	 info->SetContent(path);
	 child->AddChild(info);

	 return child;
}

// read data from xml configure file
uint32_t XMLProcess::init_read_handle(wxString conf_file)
{
	 wxString res_file=d_res_dir;
	 res_file.Append(_T("/"));
	 res_file.Append(conf_file);

	 r_doc.Load(res_file);
	 if (!r_doc.IsOk())
     {
		  return 1;
     }
     
     if (r_doc.GetRoot()->GetName() != wxT("list"))
     {
		  return 1;
     }

     return 0;
}

wxArrayString* XMLProcess::get_records(wxString conf_file)
{
	 wxArrayString* list = new wxArrayString();
     if (init_read_handle(conf_file) == 0)
     {
		  wxXmlNode *child = r_doc.GetRoot()->GetChildren();
		  while (child) 
		  {
			   if (child->GetName() == wxT("record")) 
			   {
// 					wxString ID = child->GetPropVal(wxT("ailas"),ID);
					wxString path = child->GetNodeContent();	
					list->Add(path);
			   }
			   child = child->GetNext();
		  }
		  return list;
	 }

	 return NULL;
}

